﻿#include <QSettings>
#include <QtNetwork/QNetworkInterface>
#include <QFile>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include "registerwindow.h"
#include "ui_register.h"
#include "public.h"
#include "easylogging++.h"

RegisterWindow::RegisterWindow(QWidget* parent) : QMainWindow(parent), ui(new Ui::registerWindow) {
	ui->setupUi(this);
}

bool RegisterWindow::init() {
	connect(ui->registerPushButton, &QPushButton::clicked, this, &RegisterWindow::registerHardwareInfo);

	auto succ = readRegisterInfo();
	auto localHardwareInfo = getHardwareInfo();
	if (succ) {
		bool isHardwareCorrect = localHardwareInfo == this->fileHardwareInfo;
		QDate date;
		QDateTime dt;
		dt.setDate(date.currentDate());
		QString currentDate = dt.toString("yyyyMMdd");
		bool isLastLoginCorrect = this->lastLogin == "19700101" || this->lastLogin <= currentDate;
		this->lastLogin = currentDate;
		bool isExpiryDateCorrect = this->expiryDate >= currentDate;
		if (isHardwareCorrect && isLastLoginCorrect && isExpiryDateCorrect) {
			saveRegisterInfo();
			return true;
		}
	}
	ui->hardwareInfoTextBrowser->setText(localHardwareInfo);
	return false;
}

bool RegisterWindow::readRegisterInfo() {
	QFile file("register_info.key");
	if (!file.open(QIODevice::ReadWrite)) {
		LOG(ERROR) << "register_info.key open error";
		return false;
	}
	LOG(INFO) << "read register_info.key open!";
	auto encodeContent = file.readAll();
	auto content = AESDecode(this->key, encodeContent);
	QJsonParseError errRpt;
	QJsonDocument  rootDoc = QJsonDocument::fromJson(content.toLatin1(), &errRpt); // 字符串格式化为JSON
	if (errRpt.error != QJsonParseError::NoError)
	{
		LOG(ERROR) << "JSON格式错误";
		return false;
	}
	else    // JSON格式正确
	{
		QJsonObject rootObj = rootDoc.object();
		auto it = rootObj.find("hardwareInfo");
		if (it != rootObj.end()) {
			auto value = it.value();
			if (value.isString()) {
				this->fileHardwareInfo = value.toString();
			}
		}
		it = rootObj.find("lastLogin");
		if (it != rootObj.end()) {
			auto value = it.value();
			if (value.isString()) {
				this->lastLogin = value.toString();
			}
		}
		it = rootObj.find("expiryDate");
		if (it != rootObj.end()) {
			auto value = it.value();
			if (value.isString()) {
				this->expiryDate = value.toString();
			}
		}
		return true;
	}
	return false;
}

void RegisterWindow::saveRegisterInfo() {
	QJsonObject jsonObject
	{
		{"hardwareInfo", this->fileHardwareInfo},
		{"lastLogin", this->lastLogin},
		{"expiryDate", this->expiryDate}
	};
	QJsonDocument document;
	document.setObject(jsonObject);
	QByteArray byteArray = document.toJson(QJsonDocument::Compact);
	auto encodeContent = AESEncode(this->key, byteArray);
	writeRegisterInfo(encodeContent);
}

// 获取硬件信息
QString RegisterWindow::getHardwareInfo() {
	QString content;
	auto cpuDescribe = cpuType();
	auto mac = macNumber();
	content = "cpu info:" + cpuDescribe + " mac:" + mac;
	return content;
}

QString RegisterWindow::cpuType() {
	QSettings* CPU = new QSettings("HKEY_LOCAL_MACHINE\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", QSettings::NativeFormat);
	auto cpuDescribe = CPU->value("ProcessorNameString").toString();
	delete CPU;
	LOG(INFO) << cpuDescribe.toStdString();
	return cpuDescribe;
}

QString RegisterWindow::macNumber() {
	QString strMac;

	QList<QNetworkInterface> netList = QNetworkInterface::allInterfaces();
	foreach(QNetworkInterface item, netList)
	{
		LOG(INFO) << "network flags:" << static_cast<int>(item.flags()) << " mac:" << item.hardwareAddress().toStdString();
		if ((QNetworkInterface::IsUp & item.flags()) && (QNetworkInterface::IsRunning & item.flags()))
		{
			if (strMac.isEmpty() || strMac < item.hardwareAddress())
			{
				strMac = item.hardwareAddress();
			}
		}
	}
	return strMac;
}

void RegisterWindow::registerHardwareInfo() {
	// 读界面注册信息
	auto registerInfo = ui->registrationCodeTextEdit->toPlainText();
	// 写注册信息
	auto succ = writeRegisterInfo(registerInfo);
	if (!succ) {
		return;
	}
	// 读注册信息
	succ = readRegisterInfo();
	if (!succ) {
		return;
	}

	// 校验注册信息
	auto localHardwareInfo = ui->hardwareInfoTextBrowser->toPlainText();
	if (localHardwareInfo == this->fileHardwareInfo) {
		this->hide();
		emit showMain();
		return;
	}
	return;
}